package com.rabbiter.association.controller;

import com.rabbiter.association.config.LoginSecurityConfig;
import com.rabbiter.association.entity.Notices;
import com.rabbiter.association.entity.Users;
import com.rabbiter.association.handle.CacheHandle;
import com.rabbiter.association.msg.R;
import com.rabbiter.association.service.NoticesService;
import com.rabbiter.association.service.UsersService;
import com.rabbiter.association.utils.IDUtils;
import com.rabbiter.association.utils.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/")
@RequiredArgsConstructor
@Api(tags = "系统管理")
public class IndexController extends BaseController {

    private static final Logger Log = LoggerFactory.getLogger(IndexController.class);

    private final UsersService usersService;

    private final CacheHandle cacheHandle;

    private final NoticesService noticesService;

    private final RedisUtil redisUtil;

    private final LoginSecurityConfig loginSecurityConfig;

    private final PasswordEncoder passwordEncoder;

    @GetMapping("/sys/notices")
    @ResponseBody
    @ApiOperation(value = "获取系统通知列表")
    public R getNoticeList(String token) {

        Users user = usersService.getOne(cacheHandle.getUserInfoCache(token));
        if (ObjectUtils.isEmpty(user)) {
            return R.error("登录信息不存在，请重新登录");
        }

        if (user.getType() == 0) {

            List<Notices> list = noticesService.getSysNotices();

            return R.successData(list);
        } else if (user.getType() == 1) {

            List<Notices> list = noticesService.getManNotices(user.getId());

            return R.successData(list);
        } else {

            List<Notices> list = noticesService.getMemNotices(user.getId());

            return R.successData(list);
        }
    }

    @PostMapping("/login")
    @ResponseBody
    @ApiOperation(value = "用户登录")
    public R login(@RequestBody Map<String, String> request) {
        String userName = request.get("userName");
        String passWord = request.get("passWord");
        Users user = usersService.getUserByUserName(userName);

        // 从配置获取安全参数
        String lockKey = loginSecurityConfig.getKeyPrefix() + userName;
        int maxAttempts = loginSecurityConfig.getMaxAttempts();
        int lockMinutes = loginSecurityConfig.getLockMinutes();

        // 1. 检查账号锁定状态
        if (redisUtil.hasKey(lockKey)) {
            Integer attempts = (Integer) redisUtil.get(lockKey);
            if (attempts >= maxAttempts) {
                long remainMinutes = redisUtil.getExpire(lockKey) / 60;
                return R.error(String.format("账号已锁定，请%d分钟后重试", remainMinutes));
            }
        }

        // 2. 验证用户信息
        if (user == null) {
            return R.error("输入的用户名不存在");
        }

        // 3. 密码验证
        // !passwordEncoder.matches(passWord, user.getPassWord())
        // !passWord.equals(user.getPassWord().trim())
        if (!passwordEncoder.matches(passWord, user.getPassWord())) {
            // 原子操作：递增计数并设置过期时间
            redisUtil.incr(lockKey, 1);
            redisUtil.expire(lockKey, lockMinutes * 60L);

            int remainAttempts = maxAttempts - (Integer) redisUtil.get(lockKey);
            return R.error(String.format("密码错误，剩余尝试次数%d次", remainAttempts));
        }

        // 4. 登录成功处理
        redisUtil.del(lockKey);
        String token = IDUtils.makeIDByUUID();
        cacheHandle.addUserCache(token, user.getId());
        return R.success("登录成功", token);
    }

    @RequestMapping("/exit")
    @ResponseBody
    @ApiOperation(value = "用户退出")
    public R exit(String token) {

        Log.info("用户退出系统并移除登录信息");

        cacheHandle.removeUserCache(token);

        return R.success();
    }

    @GetMapping("/info")
    @ResponseBody
    @ApiOperation(value = "获取用户信息")
    public R info(String token) {

        Users user = usersService.getOne(cacheHandle.getUserInfoCache(token));

        return R.successData(user);
    }

    @PostMapping("/info")
    @ResponseBody
    @ApiOperation(value = "修改用户信息")
    public R info(@RequestBody Users user) {

        Log.info("修改用户信息，{}", user);

        usersService.update(user);

        return R.success();
    }

    @RequestMapping("/checkPwd")
    @ResponseBody
    @ApiOperation(value = "检查密码")
    public R checkPwd(String oldPwd, String token) {

        Users user = usersService.getOne(cacheHandle.getUserInfoCache(token));

        if (oldPwd.equals(user.getPassWord())) {

            return R.success();
        } else {

            return R.warn("原始密码和输入密码不一致");
        }
    }

    @PostMapping("/pwd")
    @ResponseBody
    @ApiOperation(value = "修改密码")
    public R pwd(String token, String password) {

        Log.info("修改用户密码，{}", password);

        Users user = usersService.getOne(cacheHandle.getUserInfoCache(token));

        user.setPassWord(password);
        usersService.update(user);

        return R.success();
    }
}